--- ========================================================= ---
---  Setup Revision, Version, Date and add to AceLibrary
--- ========================================================= ---
local VERSION = tonumber(("$Revision: 52619 $"):match("%d+"))

local DaHud = DaHud
DaHud_Module_CastingBar = DaHud:NewModule("Module_CastingBar", "AceEvent-2.0")
local self = DaHud_CastingBar
if DaHud.revision < VERSION then
	DaHud.version = "r" .. VERSION
	DaHud.revision = VERSION
	DaHud.date = ("$Date: 2007-10-19 21:07:04 -0400 (Fri, 19 Oct 2007) $"):match("%d%d%d%d%-%d%d%-%d%d")
end
DaHud.desc = "Casting Bar Module"

--- ========================================================= ---
---  Setup Locals
--- ========================================================= ---
local L = DaHud:L("DaHud_Module_CastingBar")

--- ========================================================= ---
---  On Intitalize / Setup Database
--- ========================================================= ---
function DaHud_Module_CastingBar:OnInitialize()
	self.db = DaHud:AcquireDBNamespace("Module_CastingBar")
	DaHud:RegisterDefaults("Module_CastingBar", "profile", {
	})
end

--- ========================================================= ---
---  Setup Options
--- ========================================================= ---


--- ========================================================= ---
---  On Enable
--- ========================================================= ---
function DaHud_Module_CastingBar:OnEnable()
	self:CreateFrames()
	
	self:RegisterEvent("PLAYER_TARGET_CHANGED")
	
	--self:RegisterEvent("UNIT_SPELLCAST_START");
	self:RegisterEvent("UNIT_SPELLCAST_STOP");
	self:RegisterEvent("UNIT_SPELLCAST_FAILED");
	self:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED");
	--self:RegisterEvent("UNIT_SPELLCAST_DELAYED");
	--self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START");
	--self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE");
	self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP");
	
	self:ScheduleRepeatingEvent("DaHud_CastingBar_ProcessAllFrames", self.ProcessAllFrames, 0.05, self)
end

--- ========================================================= ---
---  On Disable
--- ========================================================= ---
function DaHud_Module_CastingBar:OnDisable()
	self:UnregisterAllEvents();
end

--- ========================================================= ---
---  PLAYER_TARGET_CHANGED
--- ========================================================= ---
function DaHud_Module_CastingBar:PLAYER_TARGET_CHANGED()

end

--- ========================================================= ---
---  UNIT_SPELLCAST_START
--- ========================================================= ---
function DaHud_Module_CastingBar:UNIT_SPELLCAST_START(arg1)

end

--- ========================================================= ---
---  UNIT_SPELLCAST_STOP
--- ========================================================= ---
function DaHud_Module_CastingBar:UNIT_SPELLCAST_STOP(arg1)
	for i=1, DaHud.db.namespaces.Module_Bars.profile.number do
		local cb = getglobal("DaHudFrame"..i.."CB")
		if arg1 == cb.Unit then
			if cb.Type == "cast" then
				cb.Type = "stop"
				cb.oldType = "cast"
			end
		end
	end
end

--- ========================================================= ---
---  UNIT_SPELLCAST_FAILED
--- ========================================================= ---
function DaHud_Module_CastingBar:UNIT_SPELLCAST_FAILED(arg1)
	for i=1, DaHud.db.namespaces.Module_Bars.profile.number do
		local cb = getglobal("DaHudFrame"..i.."CB")
		if arg1 == cb.Unit then
			if not(cb.Type == "channel") then
				cb.Type = "fail"
				cb.oldType = "fail"
			end
		end
	end
end

--- ========================================================= ---
---  UNIT_SPELLCAST_INTERRUPTED
--- ========================================================= ---
function DaHud_Module_CastingBar:UNIT_SPELLCAST_INTERRUPTED(arg1)
	for i=1, DaHud.db.namespaces.Module_Bars.profile.number do
		local cb = getglobal("DaHudFrame"..i.."CB")
		if arg1 == cb.Unit then
			cb.Type = "fail"
			cb.oldType = "fail"
		end
	end
end

--- ========================================================= ---
---  UNIT_SPELLCAST_DELAYED
--- ========================================================= ---
function DaHud_Module_CastingBar:UNIT_SPELLCAST_DELAYED(arg1)

end

--- ========================================================= ---
---  UNIT_SPELLCAST_CHANNEL_START
--- ========================================================= ---
function DaHud_Module_CastingBar:UNIT_SPELLCAST_CHANNEL_START(arg1)

end

--- ========================================================= ---
---  UNIT_SPELLCAST_CHANNEL_UPDATE
--- ========================================================= ---
function DaHud_Module_CastingBar:UNIT_SPELLCAST_CHANNEL_UPDATE(arg1)

end

--- ========================================================= ---
---  UNIT_SPELLCAST_CHANNEL_STOP
--- ========================================================= ---
function DaHud_Module_CastingBar:UNIT_SPELLCAST_CHANNEL_STOP(arg1)
	for i=1, DaHud.db.namespaces.Module_Bars.profile.number do
		local cb = getglobal("DaHudFrame"..i.."CB")
		if arg1 == cb.Unit then
			if cb.Type == "channel" then
				cb.Type = "stop"
				cb.oldType = "channel"
			end
		end
	end
end

--- ========================================================= ---
---  Create Frame
--- ========================================================= ---
function DaHud_Module_CastingBar:CreateFrame(frametype, framename, parent, vals)
	local name, show, bg, tex, framestrata, framelevel, width, height, scale, posx, posy, point, anchor, relative, unit, type, custom, animate, castingbar = unpack(DaHud.db.namespaces.Module_Bars.profile[vals])
	local f = CreateFrame(frametype, framename, parent)

	f:SetWidth(width)
	f:SetHeight(height)
	f:SetPoint("Center", parent, "Center", 0, 0)
	f:SetFrameStrata(framestrata)
	f:SetFrameLevel(10)
	
	local t = f:CreateTexture(framename.."Texture", "ARTWORK")
	t:SetTexture("Interface\\Addons\\DaHud\\Art\\CBCenter")

	local gap_top, gap_bottom, gap_left, gap_right = 7, 7, 0, 0
	local p = 1
	local gap_top_p = gap_top / height;    
	local gap_bottom_p = gap_bottom / height;
	local h = (height - gap_top - gap_bottom) * p;
	local top = 1-(p-(gap_top_p));
	local bottom = 1-gap_bottom_p;
	local top = top - ((gap_top_p+gap_bottom_p)*(1-p));
	t:SetHeight(h);
	t:SetWidth(width);
	t:SetTexCoord(0, 1, top, bottom );
	t:SetPoint(point, framename, relative, gap_left, gap_bottom);

	f:Show()

	return f
end

--- ========================================================= ---
---  Create Frames
--- ========================================================= ---
function DaHud_Module_CastingBar:CreateFrames()
	for i=1, DaHud.db.namespaces.Module_Bars.profile.number do
		self:CreateFrame("Frame", "DaHudFrame"..i.."CB", getglobal("DaHudFrame"..i), "hudframe"..i)
	end
end

--- ========================================================= ---
---  Update All Frames
--- ========================================================= ---
function DaHud_Module_CastingBar:UpdateAllFrames()

end

--- ========================================================= ---
---  Process All Frames
--- ========================================================= ---
function DaHud_Module_CastingBar:ProcessAllFrames()
	for i=1, DaHud.db.namespaces.Module_Bars.profile.number do
		self:ProcessFrame("DaHudFrame"..i, "hudframe"..i)
	end
end

--- ========================================================= ---
---  Process Frame
--- ========================================================= ---
function DaHud_Module_CastingBar:ProcessFrame(framename, vals)
	local name, show, bg, tex, framestrata, framelevel, width, height, scale, posx, posy, point, anchor, relative, unit, type, custom, animate, castingbar = unpack(DaHud.db.namespaces.Module_Bars.profile[vals])
	local gap_top, gap_bottom, gap_left, gap_right = 7, 7, 0, 0
	local r, g, b, a, p, v, time
	local spell, rank, displayName, icon, startTime, endTime
	local f = getglobal(framename.."CB")
	local texture = getglobal(framename.."CBTexture")

	if castingbar then
		f:Show()
	else
		f:Hide()
		return
	end

	if not(UnitExists(unit)) then
		f.Unit = nil
		f.Type = nil
		f.endTime = nil
		f.oldType = nil
		f.Fade = nil
		f:Hide()
		return
	else
		f:Show()
	end
	
	spell, rank, displayName, icon, startTime, endTime = UnitCastingInfo(unit)
	if spell then
		f:Show()
		f.Unit = unit
		f.Type = "cast"
		f.endTime = endTime
		f.oldType = nil
		f.Fade = nil
	else
		spell, rank, displayName, icon, startTime, endTime = UnitChannelInfo(unit)
		if spell then
			f:Show()
			f.Unit = unit
			f.Type = "channel"
			f.oldType = nil
			f.Fade = nil
		elseif f.Type == "stop" then
			f.endTime = nil
			if not(f.Fade) then
				f.Fade = 1
			end
		elseif f.Type == "fail" then
			f.endTime = nil
			if not(f.Fade) then
				f.Fade = 1
			end
		else
			if f.endTime and (GetTime() < (f.endTime / 1000)) then
				f.Type = "fail"
				f.oldType = "fail"
			end
		end
	end
	
	if f.endTime and (GetTime() > (f.endTime / 1000)) then
		f.endTime = nil
		f.Type = "stop"
		f.oldType = "cast"
	end
	
	if tex == "left" then
		texture:SetTexture("Interface\\Addons\\DaHud\\Art\\CBLeft")
	elseif tex == "right" then
		texture:SetTexture("Interface\\Addons\\DaHud\\Art\\CBRight")
	elseif tex == "center" then
		texture:SetTexture("Interface\\Addons\\DaHud\\Art\\CBCenter")
	elseif tex == "double" then
		texture:SetTexture("Interface\\Addons\\DaHud\\Art\\CBDouble")
	end
	
	if f.Type == "cast" then
		if startTime and endTime then
			p = (GetTime() - (startTime/1000)) / ((endTime/1000) - (startTime/1000))
			r, g, b, a = unpack(DaHud.db.profile.colors.spellcasting)
		end
	elseif f.Type == "channel" then
		if startTime and endTime then
			p = 1 - ((GetTime() - (startTime/1000)) / ((endTime/1000) - (startTime/1000)))
			r, g, b, a = unpack(DaHud.db.profile.colors.spellchanneling)
		end
	elseif f.Type == "stop" then
		if f.oldType == "cast" then
			p = 1
			r, g, b, a = unpack(DaHud.db.profile.colors.spellcasting)
		elseif f.oldType == "channel" then
			p = -1
			r, g, b, a = unpack(DaHud.db.profile.colors.spellchanneling)
		end
	elseif f.Type == "succeeded" then
		p = 1
		r, g, b, a = unpack(DaHud.db.profile.colors.spellcasting)
	elseif f.Type == "fail" then
		p = 1
		r, g, b, a = unpack(DaHud.db.profile.colors.spellinterrupted)
	end
	
	if not(p) then
		f:Hide()
		return
	end
	
	local gap_top_p = gap_top / height;    
	local gap_bottom_p = gap_bottom / height;
	local h = (height - gap_top - gap_bottom) * p;
	local top    = 1-(p-(gap_top_p));
	local bottom = 1-gap_bottom_p;
	local top = top  - ((gap_top_p+gap_bottom_p)*(1-p));
	texture:SetHeight(h);
	texture:SetWidth(width);
	texture:SetTexCoord(0, 1, top, bottom );
	texture:SetPoint(point, framename.."CB", relative, gap_left, gap_bottom);
	
	if f.Fade then
		f.Fade = f.Fade - 0.05
		a = f.Fade
	end
	
	if f.Fade and f.Fade <= 0 then
		a = 0
		f.Type = nil
		f.oldType = nil
		f.Fade = nil
	end
		
	if r and g and b and a then
		texture:SetVertexColor(r, g, b, a)
	end
end